// 引入库
import axios from 'axios'
// 2.引入饿了么 message插件
import { Message } from 'element-ui'
// 3.引入store
import store from '@/store'

import router from '@/router'
import { getTimeStamp } from '@/utils/auth'
const timeoutDuration = 5000000000

function chrckTimeout() {
  // 1.拿出之前记录的时间
  const oldTime = getTimeStamp()
  // 2.拿出现在的时间 相减 = 经过的时间
  const currentTime = Date.now()
  // 3.定义一个超时范围,如果超过则是失败
  return currentTime - oldTime >= timeoutDuration
}

// 创建公共请求实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在请求当中添加token（如果有）
    // token 的固定格式
    // 当前我们用的校验标准叫做 jwt bearer token
    if (store.getters.token) {
      // 发现有token在注入之前,先校验时间是否有超时

      // config.headers.Authorization = 'Bearer ' + store.getters.token
      if (chrckTimeout()) {
        // 已经超时的操作
        // 1.提示错误(还是会走响应拦截,所以已经弹过窗了,所以这步可以隐藏)
        // Message.error('token 已超时)
        // 2.执行退出action清理数据
        store.dispatch('user/logout')
        // 3.跳转页面
        router.push('/login')
        // 4.停止当前的请求
        return Promise.reject(new Error('token,已超时'))
      } else {
        config.headers.Authorization = 'Bearer ' + store.getters.token
      }
    }
    return config
  },
  err => {
    return Promise.reject(err)
  }
)

// 响应拦截器
// 响应拦截器当中，可以接受两个参数（res，err），两个都是函数
// 第一个函数是 网络请求成功的部分
// 第二个函数是 网络层面的失败部分
service.interceptors.response.use(
  res => {
    // 这里是网络请求成功的部分
    // 这里不一定都是对的(密码错误，账号错误等)
    // 解构服务器给我们传回去的三个数据(message，success，data)
    console.log('这里是响应拦截器utils/request.js', res)
    const { message, data, success } = res.data
    // console.log(data)
    if (success) {
      // 成功
      return data
    } else {
      Message.error(message)
      return Promise.reject(new Error(message))
    }
  },

  err => {
    // 这里是网络层面的失败(网址错误，网络中断)
    console.log('这里是网络层面的失败')
    // console.dir 才能打印出err的报错信息
    console.dir(err)
    // 这里的网络请求层面失败
    // 可能性很多,一般情况之前已经处理过
    // 就是弹出提示,并且reject即可
    // 现在对其中一种特殊情况进行独立处理
    if (err.response && err.response.data && err.response.data.code === 10002) {
      // 由于这个请求错误拦截
      // 错误的可能很多,可能连 response都没有
      // 比较严谨的写法,是先判断之前的数据是否存在
      // 这里就是 token的问题
      // 需要删除资料
      store.dispatch('user/logout')
      router.push('/login')
    } else {
      // 跳出弹窗提示错误
      Message.error(err.message)
      // 拒绝掉当前的请求promis
      // 如果在一个promis的中间，
      // 想要当前promis马上报错，
      // 需要返回一个promise.reject（）
      return Promise.reject(new Error(err.message))
    }
  }
)

// 暴露实例
export default service
